# tile from the grid
# is assigned a side (front = 0, bottom = 1, back = 2, top = 3)
(class Tile dd_matrix
	(group

	# current side
	(def int side)
	(def (array dd_matrix 4) matrix_side)

	# mesh of the tile
	(def (array dd_matrix 6) cubeMatrix)
	(def (array dd_meshTexture 6) mesh)

	(def (array dd_meshColour 4) mageMesh)
	(def (array dd_meshColour 4) mageMeshSelected)
	(def (array int 4) isMageArray)

	(def int isSelected)
	(def dd_matrix mageMatrix)

	# create tile facing front
	(function create (group)
		(group

		# initialise sides
		(for (def int i 0) (< i 4) (= i (+ i 1))
			(group
			(dd_matrix_identity this.matrix_side[i])
			(dd_matrix_rotate_x this.matrix_side[i] (dd_math_dec2rad (* i 90)))
			)
		)

		# initialise this tile as front side
		(= this.side 0)
		(dd_matrix_copy_rs this this.matrix_side[this.side])

		# initialise tile's mesh
		(for (def int i 0) (< i 6) (= i (+ i 1))
			(group
			(dd_matrix_identity this.cubeMatrix[i])
			(if (< i 4)
				(group
				(dd_matrix_rotate_x this.cubeMatrix[i] (dd_math_dec2rad (* 90 i)))
				(dd_matrix_translatem this.cubeMatrix[i] 0 0 0.5)
				)
				(group
				(dd_matrix_rotate_y this.cubeMatrix[i] (dd_math_dec2rad (+ -90 (* (- i 4) 180))))
				(dd_matrix_translatem this.cubeMatrix[i] 0 0 0.5)
				)
			)
			(dd_meshTexture_create this.mesh[i])

			(if (> i 0)
				(group
				(this.mesh[i].set_primitive DD_PRIMITIVE_RECTANGLE)
				(this.mesh[i].set_colour (* i 0.1) (* i 0.05) (* i 0.2))
				)
			)

			)
		)

		(for (def int i 0) (< i 4) (= i (+ i 1))
			(group
			(dd_meshColour_create this.mageMesh[i])
			(dd_meshColour_create this.mageMeshSelected[i])
			)
		)

		(= this.isSelected 0)

		(dd_matrix_identity this.mageMatrix)

		(for (def int i 0) (< i 4) (= i (+ i 1))
			(= this.isMageArray[i] 0)
		)

		)
	)

	# animate the tiles to the current side
	(function update (group)
		(group
		(dd_matrix_approach_rs this this.matrix_side[this.side] 0.1)
		(if this.isSelected (dd_matrix_rotate_z this.mageMatrix (dd_math_dec2rad -1)))
		)
	)

	# draw tile based on its side
	(function draw (group)
		(group
		(glPushMatrix)
		(glMultMatrixf this)
		(for (def int i 0) (< i 6) (= i (+ i 1))
			(group
			(glPushMatrix)
			(glMultMatrixf this.cubeMatrix[i])
			(this.mesh[i].draw)

			(if (&& (< i 4) this.isMageArray[i])
				(group
				(if this.isSelected
					(group
					(glMultMatrixf this.mageMatrix)
					(this.mageMeshSelected[i].draw)
					)

					(this.mageMesh[i].draw)
				)
				)
			)
			(glPopMatrix)
			)
		)
		(glPopMatrix)
		)
	)

	# advance to the next side, optionally skip animating
	(function advanceSide (group int instant)
		(group

		# advance side within limits
		(= this.side (+ this.side 1))
		(if (> this.side 3)
			(group
			(= this.side 0)
			)
		)

		# if instant, do not animate
		(if instant
			(dd_matrix_copy_rs this this.matrix_side[this.side])
		)

		)
	) # advanceSide

	(function select (group)
		(group
		(= this.isSelected 1)
		(dd_matrix_identity this.mageMatrix)
		)
	)

	(function deselect (group)
		(group
		(= this.isSelected 0)
		)
	)

	)
)
